package vsqlbuilder.logic.postgresql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.swing.JOptionPane;

public class connection {

	// TODO [High]: allow change of default port of postgresql connection, this
	// is not working right now

	private String hostName;
	private String databaseName;
	private int port;
	private String user;
	private String password;
	private Connection connectionDB;
	private Statement statementDB;
	public ResultSet resultsetDB;
	private boolean OpenConnection;

	public connection(String hostName, String databaseName, int port,
			String user, String password) {
		this.hostName = hostName;
		this.databaseName = databaseName;
		this.user = user;
		this.password = password;
		this.port = port;
		OpenConnection=false;
	}

	public boolean openConnection() {
		boolean value = false;
		// TODO [medium] Should verify all parameters, looking for empty or bad
		// formed.
		if (!this.OpenConnection) {
			try {
				Class.forName("org.postgresql.Driver");
			} catch (ClassNotFoundException cnfe) {
				System.err.println("Couldn't find driver class:");
				cnfe.printStackTrace();
			}
			String url = "jdbc:postgresql://" + this.hostName +":"+ this.port +"/"
					+ this.databaseName;
			System.out
					.println("Registered the driver ok, so let's make a connection.");
			connectionDB = null;

			try {
				// The second and third arguments are the username and password,
				// respectively. They should be whatever is necessary to connect
				// to the database.
				connectionDB = DriverManager.getConnection(url, user, password);
			} catch (SQLException se) {
				System.out
						.println("Couldn't connect: print out a stack trace for DEBUG.");
				JOptionPane.showMessageDialog(null,
					    "Error when creating connection " + se.getMessage(),
					    "Connection Error",
					    JOptionPane.ERROR_MESSAGE);
				se.printStackTrace();
				//System.exit(1);
				value=false;
			}

			if (connectionDB != null) {
				System.out.println("We connected to the database!");
				value = true;
			} else {
				System.out.println("We can't connect to the database.");
			}
		} else {
			// TODO [medium]: Here should be raised an exception, temporary a
			// message will be show
			System.out.println("First, Close the open DB connection");
		}
		OpenConnection = value;
		return value;
	}

	// TODO [medium]: validate this function
	public boolean execSQL(String SQLstatment) {
		boolean value = true;
		// TODO [low]: Verify if pointer is null if not clear to free resource
		// (if possible)
		statementDB = null;
		try {
			// ResultSet will be scrollable, will not show changes made by
			// others and will be updatable
			statementDB = connectionDB.createStatement(
					ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_UPDATABLE);
		} catch (SQLException se) {
			value = false;
			System.out
					.println("We got an exception while creating a statement:"
							+ "that probably means we're no longer connected.");
			se.printStackTrace();
			JOptionPane.showMessageDialog(null,
				    "Error when creating connection " + se.getMessage(),
				    "Connection Error",
				    JOptionPane.ERROR_MESSAGE);
			//System.exit(1);
		}
		// TODO [low]: Verify if pointer is null if not clear to free resource
		// (if possible)
		resultsetDB = null;
		try {
			resultsetDB = statementDB.executeQuery(SQLstatment);
		} catch (SQLException se) {
			value = false;
			System.out.println("We got an exception while executing our query:"
					+ "that probably means our SQL is invalid");
			se.printStackTrace();
			JOptionPane.showMessageDialog(null,
				    "Error when creating connection " + se.getMessage(),
				    "Connection Error",
				    JOptionPane.ERROR_MESSAGE);
			//System.exit(1);
		}
		return value;
	}

	public boolean closeSQL() {
		boolean value = true;
		try {
			resultsetDB.close();
			statementDB.close();
		} catch (SQLException se) {
			value = false;
			System.out
					.println("We got an exception while closing statment and resultset "
							+ "shouldn't happen: we've done something really bad.");
			se.printStackTrace();
			JOptionPane.showMessageDialog(null,
				    "Error when creating connection " + se.getMessage(),
				    "Connection Error",
				    JOptionPane.ERROR_MESSAGE);
			//System.exit(1);
		}
		return value;
	}

	public boolean closeConnection() {
		boolean value = true;
		try {
			connectionDB.close();
		} catch (SQLException se) {
			value = false;
			System.out.println("We got an exception while closing connection "
					+ "shouldn't happen: we've done something really bad.");
			se.printStackTrace();
			//System.exit(1);
			JOptionPane.showMessageDialog(null,
				    "Error when creating connection " + se.getMessage(),
				    "Connection Error",
				    JOptionPane.ERROR_MESSAGE);
		}
		OpenConnection = !value; // should be stored inverse value
		return value;
	}

	public boolean isOpenConnection() {
		return this.OpenConnection;
	}

	public void setHostName(String hostName) {
		this.hostName = hostName;
	}

	public void setDatabaseName(String databaseName) {
		this.databaseName = databaseName;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getHostName() {
		return this.hostName;
	}

	public String getDatabaseName() {
		return this.databaseName;
	}

	public String getUser() {
		return this.user;
	}

	public int getPort() {
		return this.port;
	}

	public String getPassword() {
		return this.password;
	}

}
